{
GtkDragSourceInfo *info;
GList *targets = NULL;
- GList *tmp_list;
guint32 time = GDK_CURRENT_TIME;
GdkDragAction possible_actions, suggested_action;
GdkDragContext *context;
GdkWindow *ipc_window;
int start_x, start_y;
GdkAtom selection;
+ GdkAtom *atoms;
+ guint i, n_atoms;
gboolean managed;
managed = gtk_drag_is_managed (widget);
gtk_device_grab_add (ipc_widget, pointer, FALSE);
}
- tmp_list = g_list_last (target_list->list);
- while (tmp_list)
+ atoms = gtk_target_list_get_atoms (target_list, &n_atoms);
+ for (i = 0; i < n_atoms; i++)
{
- targets = g_list_prepend (targets, tmp_list->data);
- tmp_list = tmp_list->prev;
+ targets = g_list_prepend (targets, (gpointer) atoms[i]);
}
+ g_free (atoms);
source_widgets = g_slist_prepend (source_widgets, ipc_widget);
info->selections = g_list_prepend (info->selections,
GUINT_TO_POINTER (selection));
- tmp_list = info->target_list->list;
- while (tmp_list)
- {
- gtk_selection_add_target (info->ipc_widget,
- selection,
- tmp_list->data);
- tmp_list = tmp_list->next;
- }
+ gtk_selection_add_targets (info->ipc_widget,
+ selection,
+ info->target_list);
gtk_selection_add_target (info->ipc_widget,
selection,
if (gdk_drag_context_get_protocol (info->context) == GDK_DRAG_PROTO_ROOTWIN)
{
GtkSelectionData selection_data;
- GList *tmp_list;
+ GdkAtom found = NULL;
/* GTK+ traditionally has used application/x-rootwin-drop, but the
* XDND spec specifies x-rootwindow-drop.
*/
- GdkAtom target1 = gdk_atom_intern_static_string ("application/x-rootwindow-drop");
- GdkAtom target2 = gdk_atom_intern_static_string ("application/x-rootwin-drop");
+ if (gtk_target_list_find (info->target_list, "application/x-rootwindow-drop"))
+ found = gdk_atom_intern ("application/x-rootwindow-drop", FALSE);
+ if (gtk_target_list_find (info->target_list, "application/x-rootwin-drop"))
+ found = gdk_atom_intern ("application/x-rootwin-drop", FALSE);
+ else found = NULL;
- tmp_list = info->target_list->list;
- while (tmp_list)
+ if (found)
{
- if (tmp_list->data == target1 || tmp_list->data == target2)
- {
- selection_data.selection = NULL;
- selection_data.target = tmp_list->data;
- selection_data.data = NULL;
- selection_data.length = -1;
-
- g_signal_emit_by_name (info->widget, "drag-data-get",
- info->context, &selection_data,
- time);
-
- /* FIXME: Should we check for length >= 0 here? */
- gtk_drag_drop_finished (info, GTK_DRAG_RESULT_SUCCESS, time);
- return;
- }
- tmp_list = tmp_list->next;
+ selection_data.selection = NULL;
+ selection_data.target = found;
+ selection_data.data = NULL;
+ selection_data.length = -1;
+
+ g_signal_emit_by_name (info->widget, "drag-data-get",
+ info->context, &selection_data,
+ time);
+
+ /* FIXME: Should we check for length >= 0 here? */
+ gtk_drag_drop_finished (info, GTK_DRAG_RESULT_SUCCESS, time);
+ return;
}
+
gtk_drag_drop_finished (info, GTK_DRAG_RESULT_NO_TARGET, time);
}
else
GdkDragContext *context,
GtkTargetList *target_list)
{
- GList *tmp_target;
- GList *tmp_source = NULL;
+ GtkTargetList *source_list;
+ GList *tmp_source;
+ GdkAtom result;
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), NULL);
if (target_list == NULL)
return NULL;
- tmp_target = target_list->list;
- while (tmp_target)
+ source_list = gtk_target_list_new (NULL, 0);
+ for (tmp_source = gdk_drag_context_list_targets (context);
+ tmp_source != NULL;
+ tmp_source = tmp_source->next)
{
- tmp_source = gdk_drag_context_list_targets (context);
- while (tmp_source)
- {
- if (tmp_source->data == tmp_target->data)
- return tmp_target->data;
- tmp_source = tmp_source->next;
- }
- tmp_target = tmp_target->next;
+ gtk_target_list_add (source_list, tmp_source->data);
}
+
+ result = gtk_target_list_intersects (target_list, source_list);
- return NULL;
+ gtk_target_list_unref (source_list);
+
+ return result;
}
* left to send */
};
+struct _GtkTargetList
+{
+ /*< private >*/
+ GList *list;
+ guint ref_count;
+};
+
struct _GtkIncrInfo
{
GdkWindow *requestor; /* Requestor window - we create a GdkWindow
}
}
+/**
+ * gtk_target_list_intersects:
+ * @first: the primary #GtkTargetList to intersect
+ * @second: the #GtkTargeList to intersect with
+ *
+ * Finds the first element from @first that is also contained
+ * in @second.
+ *
+ * Returns: The first matching #GdkAtom or %NULL if the lists
+ * do not intersect.
+ */
+GdkAtom
+gtk_target_list_intersects (const GtkTargetList *first,
+ const GtkTargetList *second)
+{
+ GList *l;
+
+ g_return_val_if_fail (first != NULL, NULL);
+ g_return_val_if_fail (second != NULL, NULL);
+
+ for (l = first->list; l; l = l->next)
+ {
+ if (g_list_find (second->list, l->data))
+ return l->data;
+ }
+
+ return NULL;
+}
+
/**
* gtk_target_list_add_table:
* @list: a #GtkTargetList
else if (data->target == gtk_selection_atoms[TARGETS])
{
/* List of all targets supported for this widget/selection pair */
- GdkAtom *p;
- guint count;
- GList *tmp_list;
+ GdkAtom *p, *atoms;
+ guint count, i;
GtkTargetList *target_list;
target_list = gtk_selection_target_list_get (widget,
data->selection);
- count = g_list_length (target_list->list) + 3;
+ atoms = gtk_target_list_get_atoms (target_list, &count);
data->type = GDK_SELECTION_TYPE_ATOM;
data->format = 32;
- data->length = count * sizeof (GdkAtom);
+ data->length = (count + 3) * sizeof (GdkAtom);
/* selection data is always terminated by a trailing \0
*/
*p++ = gtk_selection_atoms[TARGETS];
*p++ = gtk_selection_atoms[MULTIPLE];
- tmp_list = target_list->list;
- while (tmp_list)
- {
- *p++ = (GdkAtom) tmp_list->data;
-
- tmp_list = tmp_list->next;
- }
+ for (i = 0; i < count; i++)
+ *p++ = atoms[i];
+
+ g_free (atoms);
}
else if (data->target == gtk_selection_atoms[SAVE_TARGETS])
{